﻿Imports System
Imports System.ComponentModel.Design
Imports System.Drawing
Imports System.Windows.Forms

Namespace System.Workflow.ComponentModel.Design
    Friend NotInheritable Class PanningMessageFilter
        Inherits WorkflowDesignerMessageFilter
        ' Methods
        Friend Sub New()
        End Sub

        Protected Overrides Sub Dispose(ByVal disposing As Boolean)
            Try 
                Me.RestoreUIState
            Finally
                MyBase.Dispose(disposing)
            End Try
        End Sub

        Protected Overrides Sub Initialize(ByVal parentView As WorkflowView)
            MyBase.Initialize(parentView)
            Me.StoreUIState
            Me.RefreshUIState
        End Sub

        Protected Overrides Function OnDragEnter(ByVal eventArgs As DragEventArgs) As Boolean
            MyBase.ParentView.RemoveDesignerMessageFilter(Me)
            Return False
        End Function

        Protected Overrides Function OnKeyDown(ByVal eventArgs As KeyEventArgs) As Boolean
            If (eventArgs.KeyValue = &H1B) Then
                MyBase.ParentView.RemoveDesignerMessageFilter(Me)
            End If
            Return True
        End Function

        Protected Overrides Function OnMouseDown(ByVal eventArgs As MouseEventArgs) As Boolean
            If (eventArgs.Button = MouseButtons.Left) Then
                Me.SetPanPoint(New Point(eventArgs.X, eventArgs.Y))
            End If
            Return True
        End Function

        Protected Overrides Function OnMouseEnter(ByVal eventArgs As MouseEventArgs) As Boolean
            Me.RefreshUIState
            Return True
        End Function

        Protected Overrides Function OnMouseMove(ByVal eventArgs As MouseEventArgs) As Boolean
            If (Me.panningActive AndAlso ((eventArgs.Button And MouseButtons.Left) > MouseButtons.None)) Then
                Dim size As New Size((eventArgs.X - Me.panPoint.X), (eventArgs.Y - Me.panPoint.Y))
                Dim parentView As WorkflowView = MyBase.ParentView
                parentView.ScrollPosition = New Point((parentView.ScrollPosition.X - size.Width), (parentView.ScrollPosition.Y - size.Height))
                Me.SetPanPoint(New Point(eventArgs.X, eventArgs.Y))
            End If
            Return True
        End Function

        Protected Overrides Function OnMouseUp(ByVal eventArgs As MouseEventArgs) As Boolean
            Me.SetPanPoint(Point.Empty)
            Return True
        End Function

        Protected Overrides Function OnShowContextMenu(ByVal menuPoint As Point) As Boolean
            Dim service As IMenuCommandService = DirectCast(MyBase.GetService(GetType(IMenuCommandService)), IMenuCommandService)
            If (Not service Is Nothing) Then
                service.ShowContextMenu(WorkflowMenuCommands.ZoomMenu, menuPoint.X, menuPoint.Y)
            End If
            Return True
        End Function

        Private Sub RefreshUIState()
            MyBase.ParentView.Cursor = If(Me.panningActive, PanningMessageFilter.PanBeganCursor, PanningMessageFilter.PanReadyCursor)
            Dim service As IMenuCommandService = [TryCast](MyBase.GetService(GetType(IMenuCommandService)),IMenuCommandService)
            If (Not service Is Nothing) Then
                Dim didArray As CommandID() = New CommandID() { WorkflowMenuCommands.ZoomIn, WorkflowMenuCommands.ZoomOut, WorkflowMenuCommands.Pan, WorkflowMenuCommands.DefaultFilter }
                Dim did As CommandID
                For Each did In didArray
                    Dim command As MenuCommand = service.FindCommand(did)
                    If ((Not command Is Nothing) AndAlso command.Enabled) Then
                        command.Checked = (command.CommandID Is WorkflowMenuCommands.Pan)
                    End If
                Next
            End If
        End Sub

        Private Sub RestoreUIState()
            Dim service As IMenuCommandService = [TryCast](MyBase.GetService(GetType(IMenuCommandService)),IMenuCommandService)
            If (Not service Is Nothing) Then
                Dim did As CommandID
                For Each did In CommandSet.NavigationToolCommandIds
                    Dim command As MenuCommand = service.FindCommand(did)
                    If ((Not command Is Nothing) AndAlso command.Enabled) Then
                        command.Checked = (command.CommandID Is Me.previousCommand)
                    End If
                Next
            End If
            MyBase.ParentView.Cursor = Me.previousCursor
        End Sub

        Private Sub SetPanPoint(ByVal value As Point)
            Me.panPoint = value
            Me.panningActive = (Me.panPoint <> Point.Empty)
            MyBase.ParentView.Capture = Me.panningActive
            Me.RefreshUIState
        End Sub

        Private Sub StoreUIState()
            Dim service As IMenuCommandService = [TryCast](MyBase.GetService(GetType(IMenuCommandService)),IMenuCommandService)
            If (Not service Is Nothing) Then
                Dim did As CommandID
                For Each did In CommandSet.NavigationToolCommandIds
                    Dim command As MenuCommand = service.FindCommand(did)
                    If (((Not command Is Nothing) AndAlso command.Enabled) AndAlso command.Checked) Then
                        Me.previousCommand = command.CommandID
                        Exit For
                    End If
                Next
            End If
            Me.previousCursor = MyBase.ParentView.Cursor
        End Sub


        ' Fields
        Private Shared PanBeganCursor As Cursor = New Cursor(GetType(WorkflowView), "Resources.panClosed.cur")
        Private panningActive As Boolean
        Private panPoint As Point = Point.Empty
        Private Shared PanReadyCursor As Cursor = New Cursor(GetType(WorkflowView), "Resources.panOpened.cur")
        Private previousCommand As CommandID
        Private previousCursor As Cursor = Cursors.Default
    End Class
End Namespace

